package task;

import java.io.*;
import java.sql.*;


import channel.*;
import database.Database;


public class Task implements Runnable, TaskState {
	
	public static void main(String[] args) {
//		Task task = new Task(new ChannelMail(), new ChannelMail());
		Task task = new Task(new ChannelTime(), new ChannelTime());
		task.setId(11);
//		task.setUsr(9);
//		task.setDesc("This is Test3");
//		task.create();
		task.update();

		System.out.println(task.id);
		System.out.println(task.desc);
		System.out.println(task.channelThat.getType());
	}
	
	private int usr;
	
	private int id;
	private String desc;
	
	private Channel channelThis;
	private Channel channelThat;
	
	private int state;
	
	public Task() {
		// TODO Auto-generated constructor stub
	}
	
	public Task(Channel channelThis, Channel channelThat) {
		this.channelThis = channelThis;
		this.channelThat = channelThat;
	}
	
	public synchronized void create() {

		Connection connection = Database.getConnection();
		try {
			
			PreparedStatement pstmt = connection.prepareStatement(
									"insert into task(`desc`, `channelThisType`, `channelThatType`, " + 
									"`state`, `channelThis`, `channelThat`, `usr`) " +
									"values(?, ?, ?, ?, ?, ?, ?)");
			pstmt.setString(1, desc);
			pstmt.setInt(2, channelThis.getType());
			pstmt.setInt(3, channelThat.getType());
			pstmt.setInt(4, state);
			pstmt.setBinaryStream(5, channelThis.toStream());
			pstmt.setBinaryStream(6, channelThat.toStream());
			pstmt.setInt(7, usr);
			
			pstmt.executeUpdate();
			pstmt.close();
			connection.close();

			id = Database.getLastId();
			
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
	
	public void start() {

		Connection connection = Database.getConnection();
		try {
			
			Statement stmt = connection.createStatement();
			stmt.executeUpdate("update `task` set state = " + RUNNING + 
							   " where id = " + id);
			stmt.close();
			connection.close();
			
			TaskPool.runTask(this);
			
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
	
	public void stop() {
		
		Connection connection = Database.getConnection();
		try {
			
			Statement stmt = connection.createStatement();
			stmt.executeUpdate("update `task` set state = " + STOPPED + 
							   " where id = " + id);
			stmt.close();
			connection.close();
			
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
	
	public void delete() {

		Connection connection = Database.getConnection();
		try {
			
			Statement stmt = connection.createStatement();
			stmt.executeUpdate("update `task` set state = " + DELETED + 
							   " where id = " + id);
			stmt.close();
			connection.close();
			
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
	
	@Override
	public void run() {

		update();
		while (state == RUNNING) {
			
			int times = channelThis.THIS();
			
			for (int i=0; i<times; i++)
				channelThat.THAT();
			
			try {
				Thread.sleep(TIME_INTERVAL);
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			
			update();
		}
	}
	
	public void update() {			//get task message from database

		try {

			Connection connection = Database.getConnection();
			Statement stmt = connection.createStatement();
			ResultSet rs = stmt.executeQuery("select * from task where id = " + id);
			rs.next();
			
			desc = rs.getString("desc");
			state = rs.getInt("state");
			usr = rs.getInt("usr");
			
			Blob blob;
			ObjectInputStream input;
			
			blob = rs.getBlob("channelThis");
			input = new ObjectInputStream(blob.getBinaryStream());
			channelThis = (Channel) input.readObject();
			blob = rs.getBlob("channelThat");
			input = new ObjectInputStream(blob.getBinaryStream());
			channelThat = (Channel) input.readObject();

			stmt.close();
			connection.close();
		} catch (SQLException | IOException | ClassNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
	}
	
	public void setChannelThis(Channel channelThis) {
		this.channelThis = channelThis;
	}
	
	public void setChannelThat(Channel channelThat) {
		this.channelThat = channelThat;
	}
	
	public Channel getChannelThis(){
		return this.channelThis;
	}
	
	public Channel getChannelThat(){
		return this.channelThat;
	}
	
	public void setDesc(String desc) {
		this.desc = desc;
	}
	
	public String getDesc(){
		return this.desc;
	}
	
	public int getId(){
		return this.id;
	}
	
	public void setId(int id) {
		this.id = id;
	}
	
	public void setUsr(int usr) {
		this.usr = usr;
	}
	
	public int getState(){
		return this.state;
	}
	
	public void setState(int state)
	{
		this.state = state;
	}
	
	public void updateHot() {

		try {
			Connection connection = Database.getConnection();
			
			Statement stmt = connection.createStatement();
			stmt.executeUpdate("update `task` set hot = hot + 1" +
							   " where id = " + id);
			
			stmt.close();
			connection.close();
			
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
	
	public void modify() {			//update task message in the database
		
		try {
			Connection connection = Database.getConnection();
			
			Statement stmt = connection.createStatement();
			stmt.executeUpdate(String.format(
					"update `task` " +
					"set `desc` = '%s' " +
					"where id = %d",
					desc, id));
			
			stmt.close();
			connection.close();
			
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
	
}

